home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
tjgold.zip
/
INSTALL.004
/
FGUSER12.TXT
< prev
next >
Wrap
Text File
|
1995-05-29
|
21KB
|
547 lines
Managing the Desktop
"Oh, London is a fine town, a very
famous city where all the streets
are paved with gold and all the
maidens pretty"
George Coleman the younger, 1762-1836
The Heir at Law
Introduction
A desktop application typically has a pull-down menu, a status
bar, and a main area (in between) where windows are displayed. One
of the best known desktop applications (for us programmer types) is
Borland's integrated development environment for C and Pascal.
The unit GOLDDESK provides a set of elegant tools to make it
easy for you to create a sophisticated desktop application. We
don't need no stinkin' Turbo Vision!! (Just kidding David.)
Figure 12.1
A Typical
Desktop
Ingredients of a Desktop
A full desktop includes a pull-down menu, a status bar and one
or more windows. Gold also allows you to define a partial desktop
which has either a menu or a status bar. Having built the
individual desktop components, the desktop is constructed using the
DeskAssignxxx functions.
The Pull-down Menu
The desktop utilizes a standard Gold pull-down menu. If you
are not familiar with these menus, read Chapter 11.
Having constructed a menu, it can be added to the desktop with
the procedure DeskAssignMainMenu. This procedure is passed the
MenuBar variable which defines the menu. For example:
DeskAssignMainMenu(MainMenu);
That's all there is to it.
If, for some strange reason, you want to continue using the
desktop, but want the menu removed, just call the procedure
DeskRemoveMainMenu.
The Status Bar
At status bar is a single row of options positioned on the
bottom line of the display. It's like a menu bar without any
popups. The code used to create a status bar is exactly the same as
the code to create a menu bar.
If you want to add a status bar to the desktop, create a
variable of type MenuBar, initialize the variable with InitBar, and
use the procedure DeskAssignStatusBar to add the status bar to the
desktop. The following code fragment illustrates this approach:
var StatusBar: bar;
begin
InitBar(StatusBar);
BarAddItem(StatusBar,'~F1~ Help',1001,315,315,'',nil);
BarAddItem(StatusBar,'~Alt+X~ Exit the demo',999,301,
301,'',nil);
DeskAssignStatusBar(Statusbar);
...
end;
The status bar can be removed by calling the procedure
DeskRemoveStatusBar.
The Background
Every desktop has a background; this is the main area of the
screen which extends from the pull-down menu to the status bar.
Normally, this area is filled with a single character to provide a
plain wallpaper.
You can change the default appearance of the background by
assigning a different character to the variable DeskVars.BackChar.
Also, you can change the background color by using the GoldSetColor
procedure and assigning a new value to the DeskBack element. For
example:
DeskVars.BackChar := chr(179)
GoldSetColor(DeskBack,WhiteonGreen);
Gold provides a way for you to create more sophisticated
backgrounds. All you have to do is create a procedure following
some specific rules, and then call the DeskAssignPaintProc
procedure to instruct Gold to call your procedure every time the
background needs to be repainted.
For a procedure to be eligible as a paint procedure it must
adhere to the following rules:
The procedure must be declared as a far procedure at the root
level. Refer to section Understanding Hooks in Chapter 3 for
further information.
The procedure must be declared with no parameters.
The following procedure declaration follows these rules:
{$F+}
procedure CustomBgnd;
begin
{some code}
end; {CustomBgnd}
{$F-}
The following procedure is then called to instruct Gold to
call your procedure every time the desktop needs painting:
DeskAssignPaintProc (Hook:KeyPressedHook);
Instructs Gold to call the specified procedure every time Gold
needs to draw the background.
If, subsequently, you want to remove the custom paint
procedure, execute the command DeskRemovePaintProc.
Run the demo program DEMDESK7.PAS to see a custom paint
procedure in action.
Responding to User Input
A desktop is simply a standard way to garner user input. The
user can select items from the menu, click on the status, or press
hotkeys. The application must then respond to this input and act
accordingly. So much for the theory of desktops.
Gold takes care of managing the user input. You don't need to
explicitly invoke the menu or status bar; Gold takes care of it for
you. If the keystroke or mouse activity is directed towards the
pull-down menu, the keystroke will be passed to the menu for
processing. Similarly, status bar-related keystrokes will be passed
to the status bar for processing. If the user clicks on the top
window (if there is a window visible), the keystroke is passed to
the window for processing. Finally, if the user clicks on a window
without focus, the window is moved to the top, i.e. given focus.
Assigning an Action Procedure
Every item in the menu and status bar has an ID -- you
assigned the ID as one of the arguments in BarAddItem and
PopAddItem. When the user selects an item from the desktop, Gold
passes the ID of the selected item to a user-defined action
procedure.
All you have to do is create a procedure following some
specific rules, and then call the DeskAssignActionProc procedure to
instruct Gold to call your procedure every time the user makes a
selection.
For a procedure to be eligible as an action procedure it must
adhere to the following rules:
The procedure must be declared as a far procedure at the root
level. Refer to the section Understanding Hooks in Chapter 3
for further information.
The procedure must be declared with two passed parameters. The
first parameter is an integer and a variable parameter of type
DAction.
The following procedure declaration follows these rules:
{$F+}
procedure MyActionProc(Choice:integer;
var Action:DAction);
{}
begin
case Choice of
.....
end;
end; { MyActionProc }
{$F-}
The following procedure is then called to instruct Gold to
call your procedure after each desktop input:
DeskAssignActionProc(Aproc:DeskActionProc);
Instructs Gold to call the specified procedure every time the
user makes a status bar or menu selection from the desktop.
Writing the Action procedure
The first parameter passed to the action procedure is the ID
of the item selected from the menu or status bar. The body of the
action procedure usually takes the form of a case statement which
branches to another part of the program based on the user
selection.
The second parameter passed to the action procedure is a
variable parameter of type DAction, which is an enumerated type
declared in GOLDDESK as follows:
DAction = (DFinished, Descaped, DRepaint, DNone, DCloseTop,
DCloseAll,DStop1..DStop99);
By updating this variable with a value (other than DNone) you
can instruct Gold to take some form of action. For example, if you
update the variable with a value of DRepaint, Gold will
automatically repaint the menu, status bar, background, and every
window. The following table elaborates on the actions taken buy
Gold for each of the return values:
DAction Value Meaning
DFinished Ends the desktop session and returns the code
DFinished.
DEscaped Ends the desktop session and returns the code
DEscaped.
DRepaint Forces a repaint of the desktop and all the
windows.
DNone No action is taken - this is the default value
when the action procedure doesn't modify the
variable.
DCloseTop Forces the top window to close.
DCloseAll Forces all the windows to close.
DStop1..DStop99 Ends the desktop session and returns the
appropriate stop code.
Starting a Desktop Session
Having assigned the menu, status bar and action procedure, you
are ready to launch the desktop and wait for user input. All you
have to do is call the function DeskProcessInput. This function
returns the DAction which caused the session to close (see the
above table).
A Simple Desktop Example
Listed below is the entire source code for DEMDESK1.PAS which
implements a minimalist desktop. Although the desktop doesn't have
too many features, it does illustrate all the important principles
of creating a desktop application.
var MainMenu: Bar;
SubMenu: PopUp;
Action : dAction;
procedure DefineSubMenu;
{}
begin
InitPopUp(SubMenu);
with SubMenu do
begin
PopUpAddItem(SubMenu,'~A~bout',101,65,
'Show version...ation',nil);
PopUpAddItem(SubMenu,'E~x~it',999,88,
'~Exit~ this little demo',nil);
end;
end; { DefineSubMenu }
procedure DefineMainMenu;
{}
begin
InitBar(MainMenu);
BarAddItem(MainMenu,'~C~hoices',100,67,302,
'Select one of two menu options',
@SubMenu);
MainMenu.Style := 2;
end; { DefineMainMenu }
procedure DisposeMenus;
{}
begin
DestroyBar(MainMenu);
DestroyPopUp(SubMenu);
end; { DisposeMenus }
{$F+}
procedure MyActionProc(Choice:integer;var Action:DAction);
{}
begin
case Choice of
101: PromptOK(' The Gold Desktop ',
'^Copyright 1995 TechnoJock Software, Inc.|'
+'^All Rights Reserved');
999: Action := DFinished;
end;
end; { MyActionProc }
{$F-}
begin
DefineSubMenu;
DefineMainMenu;
DeskAssignMainMenu(MainMenu);
DeskAssignActionProc(MyActionProc);
MouseShow(true);
CursorOff;
Action := DeskProcessInput;
CursorOn;
MouseShow(false);
DisposeMenus;
end.
Launching Desktop Windows
A desktop is really a standard framework for launching windows
or applets. Many of the Gold units include procedures which are
exclusively designed for launching windows onto the desktop. In
this section you will learn how to populate the desktop with
windows.
Understanding Modal and Non-Modal Windows
A modal window is a window which disables all other aspects of
the desktop and forces all input to the window. When a modal window
is active, the user cannot switch to another window, nor select
items from the menu or the status bar. Modal windows are ideal for
error messages or dialogs which require immediate input, e.g. an
open file dialog.
Non-modal windows, on the other hand, can lose focus and form
the heart of a true desktop application. Examples of non-modal
windows include a file browser, calculator and calendar. Borland
Pascal uses non-modal windows for the edit windows where the source
code is managed.
Launch-able Gold Components
Many of the Gold units include primary procedures which begin
with the word Run, e.g. RunCalculator, RunBrowse, etc. When the
object can also be used on a desktop there is a related Launch
function, e.g. LaunchCalculator, LaunchBrowse.
Listed below is a summary of all the Gold procedures which can
be used to launch non-modal windows onto the desktop.
LaunchCalendar(StartDate:Dates;Tit:string): byte;
Adds a month-at-a-glance window to the desktop. The arguments
passed to this procedure are the same as for RunCalendar discussed
in Chapter 7. The function returns the number (or handle) of the
newly created window.
LaunchCalculator(Tit:string): byte;
Adds a push-button calculator to the desktop. The arguments
passed to this procedure are the same as for RunCalculator
discussed in Chapter 8. The function returns the number (or handle)
of the newly created window.
LaunchBrowse(var ListDetails: ListCfg;Tit:StrScreen;
CloseProc:ListCloseProc):byte;
Launches a browser for viewing the contents of an array or
linked list. The arguments passed to this procedure are discussed
in Chapter 14. The function returns the number (or handle) of the
newly created window.
LaunchBrowseFile(Fname:PathStr;Tit:StrScreen):byte;
Launches a browser for viewing the contents of a file. The
arguments passed to this procedure are the same as for
RunBrowseFile discussed in Chapter 14. The function returns the
number (or handle) of the newly created window.
LaunchList(var ListDetails: ListCfg;Tit:StrScreen;
CloseProc:ListCloseProc): byte;
Adds a list window to the desktop. The arguments passed to this
procedure are discussed in Chapter 14. The function returns the
number (or handle) of the newly created window.
LaunchGrid(var ListDetails: ListCfg;Tit:StrScreen):byte;
Adds a list window to the desktop. The arguments passed to
this procedure are the same as for RunGrid discussed in Chapter 14.
The function returns the number (or handle) of the newly created
window.
LaunchMemo(var MemoDetails: MemoCfg;Tit:StrScreen;
CloseProc:MemoCloseProc): byte;
Adds a memo window to the desktop. The arguments passed to
this procedure are discussed in Chapter 15. The function returns
the number (or handle) of the newly created window.
LaunchFormInit(X1,Y1,X2,Y2,style:byte;CloseProc:FormCloseProc):byte
LaunchForm(StartField:byte);
These functions are used to create non-modal IO forms, and are
discussed in more detail in Chapter 16.
The demo files DEMDESK2.PAS to DEMDESK5.PAS illustrate many of
the above launch functions.
Positioning New Windows
Most desktop applications place a new window down and to the
right of the (old) top window. Complications arise when the top
window is located near the right or the bottom of the desktop where
there is insufficient room for the new window.
Gold offers the following two functions to help you calculate
the dimensions of a new window:
DeskNextWinDim(var X1,Y1,X2,Y2: shortint; MinWidth,MinDepth:
longint);
Updates the first four parameters with a set of coordinates
which can be used to size a new window that is about to be added to
the desktop.
DeskNextWinCoords(var TLX,TLY: byte);
Updates the passed parameters with the appropriate coordinates
(of the top left of the window) which can be assigned to a new
window that is about to be added to the desktop.
Displaying Modal Windows
There is nothing to stop you from using modal windows on the
desktop. For example, you might use PromptStr to ask the user to
input a password. In fact, most desktop applications use both modal
and non-modal windows. In Borland Pascal, for example, a modal
window is used to prompt for confirmation during a multiple search
and replace operation.
However, always remember that a modal window must be removed
before the user can access the menu, status bar, or other windows.
So use modal windows sparingly.
Adding a Traditional "Window" menu
If you like to conform to Microsoft Windows and DOS desktop
applications standards, you should consider adding Window and Help
items to the pull-down menu. The contents of the Help menu is
application specific, but the Window menu often displays a standard
set of items (see Figure 12.2).
You create a window pop-up just like any other pop-up -- by
adding items to a PopUpMenu, and by responding to the menu choices
in the action procedure. The good news is that you do not have to
write your own tiling and cascading procedures. GOLDDESK includes
the following procedures to help with window management:
Figure 12.2
A Standard
Window Menu
DeskCloseAllWindows: boolean;
Closes all the windows on the desktop. If the function returns
FALSE, one or more window could not be closed. This might occur,
for example, when an IO form is closed but the value entered into a
field is not valid.
DeskNextWin;
Changes focus to the next window in the list.
DeskPrevWin;
Changes focus to the previous window in the list.
DeskStretchTopWin: boolean;
Lets the user manually (without the mouse) stretch the window.
A FALSE is returned if the window cannot be stretched.
DeskZoomTopWin: boolean;
Makes the top window the size of the desktop. A FALSE is
returned if the window cannot be zoomed.
DeskMoveTopWin: boolean;
Lets the user manually (without the mouse) move the top
window. A FALSE is returned if the window cannot be moved.
DeskCascade;
Arranges all the windows, cascading from the top left of the
desktop.
DeskTile: boolean;
Tiles all the windows on the desktop. A FALSE is returned if
the one or more windows cannot be tiled.
DeskWinList;
Displays a window listing all the files and allows the user to
change focus.
You can copy and paste the window related code from the demo
file DEMDESK6.PAS into your own desktop application.
Implementing a Hind Hook
A desktop hind hook is a procedure which is called every time
an input has been processed by the desktop. A hind hook can be used
to change the grayed status of menu items based on the window with
focus, for example.
All you have to do is create a procedure following some
specific rules, and call the DeskAssignHindHook procedure to
instruct Gold to call your procedure every time some input has been
processed.
For a procedure to be eligible as a desktop hind hook, it must
adhere to the following rules:
The procedure must be declared as a far procedure at the root
level. Refer to the section Understanding Hooks in Chapter 3
for further information.
The procedure must be declared with no parameters.
The following procedure declaration follows these rules:
{$F+}
procedure CustomHook;
begin
{some code}
end; {CustomHook}
{$F-}
The following procedure is then called to instruct Gold to
call your procedure every time the desktop needs painting:
DeskAssignHindHook (Hook:KeyPressedHook);
Instructs Gold to call the specified procedure every time Gold
has processed an input to the desktop..
If, subsequently, you want to remove the hind hook procedure,
execute the command DeskRemoveHindHook.
Run the demo program DEMOVIEW.PAS to see a custom hind hook in
action.